package mornd.test2;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.ControllerAdviceBean;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: mornd
 * @dateTime: 2023/5/9 - 1:28
 * @ControllerAdvice 中处理全局异常
 */
public class App {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
        MockHttpServletRequest request = new MockHttpServletRequest();
        MockHttpServletResponse response = new MockHttpServletResponse();

        ExceptionHandlerExceptionResolver resolver = context.getBean(ExceptionHandlerExceptionResolver.class);

        HandlerMethod handlerMethod = new HandlerMethod(new Controller1(), Controller1.class.getMethod("foo"));

        // 获取所有 @ControllerAdvice 类中标注 @ExceptionHandler 的方法
        Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> adviceCache = resolver.getExceptionHandlerAdviceCache();
        System.out.println(adviceCache);

        Exception e = new Exception("my exception...");
        ModelAndView mav = resolver.resolveException(request, response, handlerMethod, e);
        System.out.println(mav);
        System.out.println(response.getContentAsString());
    }

    @Configuration
    public static class WebConfig {

        @ControllerAdvice
        static class Controller2 {
            @ExceptionHandler
            @ResponseBody
            public Map handle(Exception e) {
                return new HashMap<String, Object>() {{
                    put("error", e.getMessage());
                }};
            }
        }

        @Bean
        public ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver() {
            ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
            resolver.setMessageConverters(Collections.singletonList(new MappingJackson2HttpMessageConverter()));
            // resolver.afterPropertiesSet();
            return resolver;
        }
    }

    static class Controller1 {
        public void foo() {}
    }
}
